import pygame

from pygame.sprite import Sprite
from random import randint

SCREEN_RECT=pygame.Rect(0,0,1920,1080)
FIRE_BULLET=pygame.USEREVENT+1
INVINCIBLE_TIME = pygame.USEREVENT+2

SMALL_ENERGY = 2
MID_ENERGY = 5
BIG_ENERGY = 10
BOSS01_ENERGY=60
class GameSprites(Sprite):
    def __init__(self, image_name,energy=1,speed=1,index=0,is_hit=False):
        super().__init__()
        self.index=index
        self.speed = speed
        self.is_hit=is_hit
        self.image=pygame.image.load(image_name).convert_alpha()
        self.rect = self.image.get_rect()
        self.energy=energy

    def update(self):
        self.rect.y+=self.speed


class Bg_Ground(GameSprites):
    def __init__(self, file_name,isAlt=False):
        super().__init__(file_name,speed=1)
        if isAlt:
            self.rect.y=-self.rect.height
    def update(self):
        super().update()
        if self.rect.y>=SCREEN_RECT.height:
            self.rect.y=-SCREEN_RECT.height

class Small_enermy(GameSprites):
    def __init__(self):
        super().__init__("image/enemy1.png", energy=SMALL_ENERGY,speed=randint(4,6))
        self.switch_small = []
        self.switch_small.extend([ \
            pygame.image.load("image/enemy1.png") , \
            pygame.image.load("image/enemy1_2.png")
        ])

        self.destroy_images = []
        self.isDown=False
        self.switch =True
        self.destroy_images.extend([ \
            pygame.image.load("image/enemy1_down1.png").convert_alpha() , \
            pygame.image.load("image/enemy1_down2.png").convert_alpha() , \
            pygame.image.load("image/enemy1_down3.png").convert_alpha() , \
            pygame.image.load("image/enemy1_down4.png").convert_alpha() , \
            ])
        self.x_speed=randint(1,3)
        self.direction = 1
        self.num =randint(0,1)
        self.delay=100
        if self.num==0:
           self.rect.left , self.rect.top =\
                randint(0,(SCREEN_RECT.width-self.rect.width)//2),\
                randint(-2*self.rect.height,-self.rect.height)
        elif self.num==1:
            self.rect.left , self.rect.top = \
                  randint((SCREEN_RECT.width-self.rect.width)//2,SCREEN_RECT.width-self.rect.width ) , \
                  randint(-2*self.rect.height,-self.rect.height)
        self.mask=pygame.mask.from_surface(self.image)
    def update(self):
        if self.isDown==False:
            super().update()
            if self.switch == True :
                self.image = self.switch_small[0]
            else :
                self.image = self.switch_small[1]

            if self.delay % 5 == 0 :
                self.switch = not self.switch
            self.delay -= 1
            if self.delay == 0 :
                self.delay = 100

            if self.num==0:
                self.rect.x += self.x_speed * self.direction

                if self.rect.right>SCREEN_RECT.width or  (self.rect.left<0 and self.rect.right>0):
                    self.direction *= -1
                    self.x_speed=randint(1,3)
            else:

                self.rect.x -= self.x_speed * self.direction

                if self.rect.right > SCREEN_RECT.width or self.rect.left < 0 :
                    self.direction *= -1
                    self.x_speed = randint(1 , 3)

            if self.rect.top >= SCREEN_RECT.height :
                 self.rect.top=randint(-3 * self.rect.height , -self.rect.height)

        else:
            self.down()

    def down(self):
        if not self.delay%4:
            self.image=self.destroy_images[self.index]
            self.index=(self.index+1)%4
            if self.index==0:
                self.kill()
        self.delay -= 1
        if self.delay == 0 :
            self.delay = 100

class Mid_enermy(GameSprites):

    def __init__(self):
        super().__init__("image/enemy2.png",energy=MID_ENERGY,speed=randint(2,3))
        self.isDown = False
        self.delay=100
        self.hit_image=pygame.image.load("image/enemy2_hit.png")
        self.destroy_images = []
        self.destroy_images.extend([ \
            pygame.image.load("image/enemy2_down1.png").convert_alpha() , \
            pygame.image.load("image/enemy2_down2.png").convert_alpha() , \
            pygame.image.load("image/enemy2_down3.png").convert_alpha() , \
            pygame.image.load("image/enemy2_down4.png").convert_alpha() , \
            ])
        self.rect.left , self.rect.top = \
            randint(0 , SCREEN_RECT.width - self.rect.width) , \
            randint(-8* self.rect.height , 0)
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        if not self.isDown:
            self.rect.y+=self.speed
            if self.rect.top >= SCREEN_RECT.height:
                self.rect.left , self.rect.top = \
                    randint(0 , SCREEN_RECT.width - self.rect.width) , \
                    randint(-8* self.rect.height , -self.rect.height)
                self.speed=randint(1,5)
            if self.is_hit:
                self.image=self.hit_image
                self.is_hit=False
            else:
                self.image=pygame.image.load("image/enemy2.png")
        else:
            self.down()
    def down(self):
            if self.delay%5==0:
               self.image = self.destroy_images[self.index]
               self.index = (self.index + 1) % 4

               if self.index ==0:
                  self.kill()

            self.delay-=1
            if self.delay==0:
                self.delay=100

class Bullet_Supply(GameSprites):
    def __init__(self):
        super().__init__("image/bullet_supply.png",speed=2)
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        self.rect.top+=self.speed
        if self.rect.top > SCREEN_RECT.height:
           self.kill()

class Bomb_Supply(GameSprites):
    def __init__(self):
        super().__init__("image/bomb_supply.png",speed=2)
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        self.rect.top+=self.speed
        if self.rect.top > SCREEN_RECT.height:
           self.kill()

class Big_enermy(GameSprites):
    def __init__(self):
        super().__init__("image/enemy3_n1.png" , energy=BIG_ENERGY , speed=2)
        self.switch_myrabbit=[]
        self.switch_myrabbit.extend([ \
            pygame.image.load("image/enemy3_n1.png"),\
            pygame.image.load("image/enemy3_n2.png"),
            pygame.image.load("image/enemy3_n3.png"),
            pygame.image.load("image/enemy3_n4.png"),
                              ] )
        self.hit_image=pygame.image.load("image/enemy3_hit.png")
        self.destroy_images = []
        self.destroy_images.extend([ \
            pygame.image.load("image/enemy3_down1.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down2.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down3.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down4.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down5.png").convert_alpha(), \
            pygame.image.load("image/enemy3_down6.png").convert_alpha() , \
            ])
        self.switch=True
        self.isDown=False
        self.delay=100
        self.rect.left , self.rect.top = \
            randint(0 , SCREEN_RECT.width - self.rect.width),\
            randint(-10* self.rect.height ,-5* self.rect.height)
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        if self.isDown==False:
            super().update()
            if self.rect.top >= SCREEN_RECT.height :
                self.rect.left , self.rect.top = \
                    randint(0 , SCREEN_RECT.width - self.rect.width) , \
                    randint(-6 * self.rect.height , -self.rect.height)


            if self.is_hit :
                self.image = self.hit_image
                self.is_hit = False
            else:
                if self.delay % 10 == 0 :
                    self.image = self.switch_myrabbit[self.index]
                    self.index = (self.index + 1) % 4
                    self.delay -= 1
                    if self.delay == 0 :
                        self.delay = 100
        else:
            self.down()
        self.delay -= 1
        if self.delay == 0 :
            self.delay = 100
    def down(self):
            if self.delay%5==0:
                self.image = self.destroy_images[self.index]
                self.index = (self.index + 1) % 6
                if self.index == 0 :
                    self.kill()
class Boss1(GameSprites):
    def __init__(self):
        super().__init__("image/boss1/boss0.png" , energy=BOSS01_ENERGY, speed=10)
        self.switch_boss1=[]
        self.switch_boss1.extend([ \
            pygame.image.load("image/boss1/boss0.png"),\
            pygame.image.load("image/boss1/boss1.png"), \
            pygame.image.load("image/boss1/boss2.png") , \
            pygame.image.load("image/boss1/boss3.png") ,
            pygame.image.load("image/boss1/boss4.png") , \
            pygame.image.load("image/boss1/boss5.png"), \
            ])
        self.hit_image=pygame.image.load("image/boss1/boss1hit.png")
        self.destroy_images = []
        self.destroy_images.extend([ \
            pygame.image.load("image/enemy3_down1.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down2.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down3.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down4.png").convert_alpha(),\
            pygame.image.load("image/enemy3_down5.png").convert_alpha(), \
            pygame.image.load("image/enemy3_down6.png").convert_alpha() , \
            ])
        self.switch=True
        self.direction=-1
        self.isDown=False
        self.delay=100
        # 创建子弹精灵族
        self.bullets = pygame.sprite.Group()
        self.rect.left , self.rect.top = \
            randint(0 , SCREEN_RECT.width - self.rect.width),\
            randint(-10* self.rect.height ,-5* self.rect.height)
        self.mask = pygame.mask.from_surface(self.image)
    def boss_update(self):

        if self.rect.bottom<=360:
            super().update()
        else:
            self.rect.x += self.direction * randint(1, 5)
            if self.rect.left<=0 or self.rect.x==randint(0,960):
                self.direction *= -1
            if self.rect.right >=SCREEN_RECT.width or self.rect.x==randint(960,1920):
               self.direction *= -1
    def boss_fired(self):
        boss_bullet = Boss_Bullet()
        boss_bullet2 = Boss_Bullet()
        boss_bullet.rect.x = self.rect.left
        boss_bullet.rect.y = self.rect.bottom-30
        boss_bullet2.rect.x = self.rect.right
        boss_bullet2.rect.y = self.rect.bottom - 30
        self.bullets.add(boss_bullet,boss_bullet2)

    def update(self):
        if self.isDown==False:
            self.boss_update()
            if self.rect.top >= SCREEN_RECT.height :
                self.rect.left , self.rect.top = \
                    randint(0 , SCREEN_RECT.width - self.rect.width) , \
                    randint(-6 * self.rect.height , -self.rect.height)

            if self.is_hit :
                self.image = self.hit_image
                self.is_hit = False

            else:
                if self.delay % 5 == 0 :
                    self.image = self.switch_boss1[self.index]
                    self.index = (self.index + 1) % 6

        else:
            self.down()
        self.delay -= 1
        if self.delay == 0 :
            self.delay = 100
    def down(self):
            if self.delay%5==0:
                self.image = self.destroy_images[self.index]
                self.index = (self.index + 1) % 6
                if self.index == 0 :
                    self.kill()
            self.delay -= 1
            if self.delay == 0 :
                self.delay = 100

class MyRabbit(GameSprites):
    def __init__(self):
        super().__init__("image/me1.png" , speed=9)

        self.switch_myrabbit = []
        self.switch_myrabbit.extend([ \
            pygame.image.load("image/me1.png").convert_alpha(),
            pygame.image.load("image/me2.png").convert_alpha()
        ])
        self.switch_myrabbit_pro = []
        self.switch_myrabbit_pro.extend([ \
            pygame.image.load("image/me_pro1.png").convert_alpha() ,
            pygame.image.load("image/me_pro2.png").convert_alpha()
        ])

        self.destroy_image = []
        self.destroy_image.extend([\
            pygame.image.load("image/me_destroy_1.png").convert_alpha() ,\
            pygame.image.load("image/me_destroy_2.png").convert_alpha() ,\
            pygame.image.load("image/me_destroy_3.png").convert_alpha() ,\
            pygame.image.load("image/me_destroy_4.png").convert_alpha() ,\
            ])
        #设置飞机的初始位置
        self.rect.left , self.rect.top = \
            (SCREEN_RECT.width - self.rect.width) // 2 , \
            (SCREEN_RECT.height-self.rect.height- 60)
        #创建子弹精灵族
        self.bullets=pygame.sprite.Group()
        # 创建炸弹精灵族
        self.bomb_group = pygame.sprite.Group()
        # 创建双倍子弹列表
        self.double_bullets_list = []
        # 创建炸弹补给列表
        self.bomb_list = []

        self.invincible=False
        self.life=1#我有三条命

        self.isDoubleBullet=False#我不能发射双倍子弹
        self.isBomb=False
        self.double_bullet_counts=0#剩余双倍子弹数量
        self.isAvailable_Double_Bullet=False#开关：是否获取双倍子弹
        self.isAvailable_Bomb_Bullet=False#开关：是否获取炸弹补给
        self.bomb_counts = 0  # 剩余炸弹数量
        self.switch=True
        self.delay = 100
        self.isDown=False
        self.move_right = False
        self.move_left = False
        self.move_up = False
        self.move_down = False


    def update(self):
        #双倍子弹添加到子弹列表为了统计子弹剩余数量
        if self.isAvailable_Double_Bullet==True:
            for num in range(0,randint(20,45)):
                self.double_bullets_list.append(Bullet2())
                self.double_bullets_list.append(Bullet2())
        self.double_bullet_counts=len(self.double_bullets_list)//2+len(self.double_bullets_list)%2
        self.isAvailable_Double_Bullet=False
        # 炸弹补给添加到子弹列表为了统计炸弹剩余数量
        if self.isAvailable_Bomb_Bullet == True:
           self.bomb_list.append(Bomb())
        self.isAvailable_Bomb_Bullet = False
        self.bomb_counts = len(self.bomb_list)


        if self.isDown==False :
            if self.rect.top >= 0 and self.move_up:
                self.rect.top -= self.speed
                self.move_up=False
            elif self.rect.bottom<SCREEN_RECT.height and self.move_down:
                self.rect.top+=self.speed
                self.move_down = False
            elif self.rect.left>0 and self.move_left:
                self.rect.left-=self.speed
                self.move_left = False
            elif self.rect.right<SCREEN_RECT.width and self.move_right:
                self.rect.left+=self.speed
                self.move_right = False

            if self.switch==True:
               self.image=self.switch_myrabbit[0]
            else:
               self.image=self.switch_myrabbit[1]

            self.delay -= 1
            if self.delay == 0:
                self.delay = 100
            # 每5帧切换一下飞行图片样式
            if self.delay %8== 0:
                self.switch = not self.switch
        else:
            self.down()
    def down(self):

            if self.delay%5==0:
                   self.image = self.destroy_image[self.index]
                   self.index=(self.index+1)%4
                   if self.index==0:
                       self.life-=1
                       self.isDown = False
                       self.rect.left , self.rect.top = \
                                    (SCREEN_RECT.width - self.rect.width) // 2 , \
                                    (SCREEN_RECT.height - self.rect.height - 60)

            self.delay -= 1
            if self.delay == 0 :
                self.delay = 100
    def fired(self):
            #创建子弹精灵
            bullet=Bullet1()
            #设置初始位置
            bullet.rect.midtop=self.rect.midtop
            bullet.rect.y=self.rect.top
            #添加到精灵族
            self.bullets.add(bullet)
    def fired_double_bullet(self):
        if  self.isDoubleBullet == True:
            if self.double_bullet_counts>=1:
                bullet1 = Bullet2()
                bullet1.rect.centerx = self.rect.centerx - 33
                bullet1.rect.y = self.rect.top
                bullet2 = Bullet2()
                bullet2.rect.centerx = self.rect.centerx + 33
                bullet2.rect.y = self.rect.top
                self.bullets.add(bullet1)
                self.bullets.add(bullet2)
                if self.double_bullet_counts>=2 and len(self.double_bullets_list)>0:
                    for i in range(0,2):
                        self.double_bullets_list.pop(0)
                elif self.double_bullet_counts==1 and len(self.double_bullets_list)>0:
                    self.double_bullets_list.pop(0)

    def fired_bomb(self):
        if self.isBomb == True:
            if self.bomb_counts>=1:
                bomb= Bomb()
                bomb.rect.centerx = self.rect.centerx
                bomb.rect.y = self.rect.top
                self.bomb_group.add(bomb)
                self.bomb_list.pop(0)




class Bullet1(GameSprites):
    def __init__(self):
        super().__init__("image/bullet1.png",speed=12)
        self.mask = pygame.mask.from_surface(self.image)

    def update(self):
        self.rect.top-=self.speed
        if self.rect.top<=0:
            self.kill()


class Bullet2(GameSprites):
    def __init__(self):
        super().__init__("image/bullet2.png",speed=12)
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        self.rect.top-=self.speed
        if self.rect.top<=0:
            self.kill()
class Bomb(GameSprites):
    def __init__(self):
        super().__init__("image/bomb.png",speed=20)
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        self.rect.top-=self.speed
        if self.rect.top<=0:
            self.kill()


class Boss_Bullet(GameSprites):
    def __init__(self):
        super().__init__("image/boss1/bullet.png",speed=10)
        self.mask = pygame.mask.from_surface(self.image)
    def update(self):
        self.rect.top+=self.speed
        if self.rect.top>=SCREEN_RECT.height:
            self.kill()
